﻿/**********************************************************************************
 * Project Name :   
 * Remarks      :  
 * Class Name   :  MainViewModel 
 * Version      :  v1.0.0.0 
 * Author       :  Joey Liang 
 * Description  : 
 * Created Time :  2013/8/14 22:44:13
 * Update Man   :  Joey Liang
 * Update Time  :  2013/8/14 22:44:13
************************************************************************/

using JoeyLibs.IdleStartMenu.Interfaces;
using JoeyLibs.IdleStartMenu.IViewModel;
using JoeyLibs.IdleStartMenu.Model;
using JoeyLibs.IdleStartMenu.UIUtility;
using JoeyLibs.Utility;
using JoeyLibs.Utility.Xml;
using Microsoft.Practices.Unity;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;

namespace JoeyLibs.IdleStartMenu.ViewModels
{
    public class MainViewModel : IMainViewModel
    {
        public MainViewModel(IUnityContainer container)
        {
            this.processesOpened = new List<IProcessViewModel>();
            this.menuDataProvider = container.Resolve<IDataProvider>();
        }

        #region Fields & Event

        private IList<IProcessViewModel> processesOpened;
        private IDataProvider menuDataProvider;
        private bool isMultiProcessOpened;
        private IList<ProcessModel> processModels;

        #endregion

        #region Properties
        
        #endregion

        #region Methods

        private IProcessViewModel FindProcess(ProcessModel processModel)
        {
            for (int i = 0; i < this.processesOpened.Count; i++)
            {
                IProcessViewModel item = this.processesOpened[i];
                if (item.Process == null || item.Process.HasExited)
                {
                    this.processesOpened.Remove(item);
                    i--;
                    continue;
                }

                if (item.Process.ProcessName == processModel.ProcessPath && 
                    item.ProcessModel.ProcessType == processModel.ProcessType)
                {
                    return item;
                }
            }

            return null;
        }
        
        #endregion

        #region IMainViewModel 成员
        public IList<IProcessViewModel> ProcessesOpened
        {
            get { return this.processesOpened; }
        }
        
        public IList<ProcessModel> ProcessModels
        {
            get 
            {
                if (this.processModels == null)
                {
                    this.processModels = this.menuDataProvider.Processes;
                }

                return this.processModels; 
            }
        }

        public bool IsMultiProcessOpened
        {
            get
            {
                return this.isMultiProcessOpened;
            }
            set
            {
                this.isMultiProcessOpened = value;
            }
        }

        public void CreateProcess(ProcessModel model)
        {
            IProcessViewModel p = FindProcess(model);
            if (p != null && p.Process != null && !this.isMultiProcessOpened)
            {
                UIDllImport.HandleRunningInstance(p.Process);
            }
            else
            {
                p = new ProcessViewModel();
                p.Process = UICommon.StartProcess(model.ProcessPath, model.Arguments);
                p.ProcessModel = model;
                if (p!= null)
                    this.processesOpened.Add(p);
            }
        }

        public void Update()
        {
            if (this.ProcessModels == null || this.ProcessModels.Count == 0)
            {
                return;
            }

            foreach (var item in this.ProcessModels)
            {
                if (item.ID < 0)
                {
                    item.ID = this.ProcessModels.Max(p => p.ID) + 1;
                }

                switch (item.HandleState)
                {
                    case ModelHandleState.Add:
                        this.menuDataProvider.AddProcess(item, false);
                        break;

                    case ModelHandleState.Edit:
                        this.menuDataProvider.EditProcess(item, false);
                        break;

                    case ModelHandleState.Delete:
                        this.menuDataProvider.DelProcess(item, false);
                        break;

                    default: break;
                }
            }

            this.menuDataProvider.SaveChanges();
        }

        public void UpdateOrder(ProcessModel model, int newOrderNum)
        {
            if (model == null)
            {
                return;
            }

            int plusValue = newOrderNum - model.OrderNum;
            Func<ProcessModel, bool> func;
            if (plusValue > 0)
            {
                func = p => p.OrderNum > model.OrderNum;
            }
            else
            {
                func = p=> p.OrderNum < model.OrderNum && p.OrderNum >= newOrderNum;
            }

            model.OrderNum = newOrderNum;
            UtilityCommon.ForeachHandle<ProcessModel>(this.ProcessModels.Where(func), p => 
            {
                p.OrderNum += plusValue; 
                p.HandleState = ModelHandleState.Edit;
            });
        }

        public void ImportSetting(string fileName)
        {
            XmlHelper.CopyFile(fileName, AppConfig.Instance.MenuConfigFile);
            RefreshData();
        }

        public void ExportSetting(string fileName)
        {
            XmlHelper.CopyFile(AppConfig.Instance.MenuConfigFile, fileName);
        }

        public void ResetInit()
        {
            XmlHelper.CopyFile(AppDomain.CurrentDomain.BaseDirectory + AppConfig.Instance["ResetInitFile"], 
                AppConfig.Instance.MenuConfigFile);
            RefreshData();
        }

        public void RefreshData()
        {
            this.processModels = this.menuDataProvider.GetProcesses(p => true);
        }
        #endregion
    }
}
